home *** CD-ROM | disk | FTP | other *** search
/ POINT Software Programming / PPROG1.ISO / pascal / swag / textwndw.swg / 0014_Complete WINDOW unit.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-08-24  |  23.4 KB  |  1,012 lines

  1. UNIT Win; { Win.Pas }
  2.  
  3. {$S-}{$I-}{$R-}
  4.  
  5. INTERFACE
  6.  
  7. USES Crt, Cursor, FadeUnit;
  8.  
  9. TYPE
  10.   PTitleStr = ^TitleStr;
  11.   TitleStr = STRING [63];
  12.  
  13.   PFrame = ^TFrame;
  14.   TFrame = ARRAY [1..8] OF CHAR;
  15.  
  16.   TVertFrameChars = ARRAY [1..3] OF CHAR;
  17.  
  18.   { Text color attr type }
  19.  
  20.   PTextAttr = ^TTextAttr;
  21.   TTextAttr = BYTE;
  22.  
  23.   { Window rectangle type }
  24.  
  25.   PRect = ^TRect;
  26.   TRect = RECORD
  27.     Left, Top, Right, Bottom : BYTE
  28.   END;
  29.  
  30.   PWinState = ^TWinState;
  31.   TWinState = RECORD
  32.     WindMin,
  33.     WindMax : WORD;
  34.     WHEREX,
  35.     WHEREY : BYTE;
  36.     TextAttr : TTextAttr
  37.   END;
  38.  
  39.   PWinRec = ^TWinRec;
  40.   TWinRec = RECORD
  41.     Next : PWinRec;
  42.     State : TWinState;
  43.     Title : PTitleStr;
  44.     TitleColor,
  45.     FrameColor : TTextAttr;
  46.     Size : WORD;
  47.     Buffer : POINTER
  48.   END;
  49.  
  50.   PWindowStruct = ^TWindowStruct;
  51.   TWindowStruct = RECORD
  52.     Rect : TRect;
  53.     TitleColor,
  54.     FrameColor : TTextAttr;
  55.     Title : TitleStr
  56.   END;
  57.  
  58. CONST
  59.   None = '';
  60.  
  61.   VertFrame   : TVertFrameChars = '│║█';
  62.  
  63.   { Display combination codes returned by the GetDisplay function }
  64.  
  65.   gdNoDisplay = $00; { No display }
  66.   gdMono      = $01; { Monochrome adapter w/ monochrome display }
  67.   gdCGA       = $02; { CGA w/ color display }
  68.   gdEGA       = $04; { EGA w/ color display }
  69.   gdEGAMono   = $05; { EGA w/ monochrome display }
  70.   gdPGA       = $06; { PGA w/ color display }
  71.   gdVGAMono   = $07; { VGA w/ monochrome analog display }
  72.   gdVGA       = $08; { VGA w/ color analog display }
  73.   gdMCGADig   = $0A; { MCGA w/ digital color display }
  74.   gdMCGAMono  = $0B; { MCGA w/ monochrome analog display }
  75.   gdMCGA      = $0C; { MCGA w/ color analog display }
  76.   gdUnknown   = $FF; { Unknown display type }
  77.  
  78.   { Window frame classes }
  79.  
  80.   SingleFrame : TFrame       = '┌─┐││└─┘';
  81.   DoubleFrame : TFrame       = '╔═╗║║╚═╝';
  82.   SingleDoubleFrame : TFrame = '╓─╖║║╙─╜';
  83.   DoubleSingleFrame : TFrame = '╒═╕││╘═╛';
  84.   BarFrame : TFrame          = '█▀████▄█';
  85.  
  86.   { Window frame constants }
  87.  
  88.   frNone         = 0;  { Window has no frame }
  89.   frSingle       = 1;  { Window has single frame }
  90.   frSingleDouble = 2;  { Window has single (horiz) and double (vert) frames }
  91.   frDouble       = 3;  { Window has double frame }
  92.   frDoubleSingle = 4;  { Window has double (horiz) and single (vert) frames }
  93.   frBar          = 5;  { Window has a rectangular bar frame }
  94.  
  95.   { Shadow color attributes }
  96.  
  97.   winShadowAttr : TTextAttr = $07;
  98.  
  99.   FontOpenReg : ARRAY [1..10] OF BYTE =
  100.     ($02, $04, $04, $07, $05, $00, $06, $04, $04, $02);
  101.   FontCloseReg : ARRAY [1..10] OF BYTE =
  102.     ($02, $03, $04, $03, $05, $10, $06, $0E, $04, $00);
  103.  
  104.   FadeDelay = 10; { Fade screen delay time for
  105.     SaveDosScreen and RestoreDosScreen functions }
  106.  
  107. VAR
  108.   WinShadow : BOOLEAN;
  109.   WinCount : INTEGER;
  110.   TopWindow : PWinRec;
  111.   WinExplodeDelay, ScreenHeight, WinFrame : BYTE;
  112.   ScreenWidth : WORD;
  113.   Screen : POINTER;
  114.  
  115. FUNCTION  GetDisplay : BYTE;
  116. PROCEDURE SetTextFont (VAR Font; StartChar, BytePerChar, CharCount : BYTE);
  117. FUNCTION  GetTextFont (FontCode : BYTE) : POINTER;
  118. PROCEDURE WriteStr (X, Y : BYTE; S : STRING; Color : TTextAttr);
  119. PROCEDURE WriteStrV (X, Y : BYTE; S : STRING; Color : TTextAttr);
  120. PROCEDURE WriteChar (X, Y, Count : BYTE; Ch : CHAR; Color : TTextAttr);
  121. PROCEDURE FillWin (Ch : CHAR; Color : TTextAttr);
  122. PROCEDURE ReadWin (VAR Buf);
  123. PROCEDURE WriteWin (VAR Buf);
  124. FUNCTION  WinSize : WORD;
  125. PROCEDURE SaveWin (VAR W : TWinState);
  126. PROCEDURE RestoreWin (VAR W : TWinState);
  127. PROCEDURE GetFrame (FrameNum : BYTE; VAR Frame : TFrame);
  128. PROCEDURE FrameWin (Title : TitleStr;
  129.                     Frame : TFrame; TitleColor, FrameColor : TTextAttr);
  130. PROCEDURE UnFrameWin;
  131. FUNCTION  ScrReadChar (X, Y : BYTE) : CHAR;
  132. PROCEDURE ScrWriteChar (X, Y : BYTE; Ch : CHAR);
  133. FUNCTION  ScrReadAttr (X, Y : BYTE) : TTextAttr;
  134. PROCEDURE ScrWriteAttr (X, Y : BYTE; Color : TTextAttr);
  135. PROCEDURE WindowIndirect (Rect : TRect);
  136. FUNCTION  PtInRect (X, Y : BYTE; Rect : TRect) : BOOLEAN;
  137. PROCEDURE GetWindowRect (VAR Rect : TRect);
  138. PROCEDURE GetWindowRectExt (X1, Y1, X2, Y2 : BYTE; VAR Rect : TRect);
  139. PROCEDURE ClearWin (X1, Y1, X2, Y2 : BYTE; Color : TTextAttr);
  140. PROCEDURE ShadowWin (X1, Y1, X2, Y2 : BYTE);
  141. PROCEDURE CreateWin (X1, Y1, X2, Y2 : BYTE;
  142.                     TitleColor, FrameColor : TTextAttr; Title : TitleStr);
  143. PROCEDURE CreateWinIndirect (WS : TWindowStruct);
  144. FUNCTION  OpenWin (X1, Y1, X2, Y2 : BYTE;
  145.                   TitleColor, FrameColor : TTextAttr; Title : TitleStr) : BOOLEAN;
  146. FUNCTION  OpenWinIndirect (WS : TWindowStruct) : BOOLEAN;
  147. FUNCTION  CloseWin : BOOLEAN;
  148. FUNCTION  MoveWin (Left, Top : BYTE) : BOOLEAN;
  149. FUNCTION  SaveDOSScreen (UseFade, RestoreScreen : BOOLEAN) : BOOLEAN;
  150. FUNCTION  RestoreDOSScreen (UseFade : BOOLEAN) : BOOLEAN;
  151. PROCEDURE SetBlink (BlinkOn : BOOLEAN);
  152.  
  153. IMPLEMENTATION
  154.  
  155. {$L win.obj}
  156.  
  157. VAR OldCursor : WORD;
  158.  
  159. FUNCTION MakeWord (HI, LO : BYTE) : WORD; assembler;
  160. Asm
  161.   MOV AH, HI
  162.   MOV AL, LO
  163. END; { MakeWord }
  164.  
  165. FUNCTION GetDisplay; assembler;
  166. Asm
  167. MOV AX, 1A00h
  168.   INT 10h
  169.   MOV AL, BL
  170. END; { GetDisplay }
  171.  
  172. PROCEDURE SetRegisters; near; assembler;
  173. asm
  174.   MOV AX, SEG @Data
  175.   MOV DS, AX
  176.   MOV CX, 0002h
  177.   MOV DX, 03C4h
  178.   CALL @@1
  179.   MOV CX, 0003h
  180.   MOV DL, 0CEh
  181. @@1 :
  182.   LODSB
  183.   OUT DX, AL
  184. INC DX
  185.   LODSB
  186. OUT DX, AL
  187.   DEC DX
  188.   LOOP @@1
  189. END; { SetRegisters }
  190.  
  191. PROCEDURE SetTextFont; assembler;
  192. Asm
  193.   MOV BX, SegA000
  194.   PUSH DS
  195.   MOV AX, WORD PTR [Font + 2]
  196.   MOV DS, AX
  197.   XOR AX, AX
  198.   MOV AL, StartChar
  199.   MOV DI, AX
  200.   MOV SI, WORD PTR [Font]
  201.   MOV AX, BX
  202.   MOV BL, BytePerChar
  203. XOR BH, BH
  204.   PUSH ES
  205. MOV ES, AX
  206.   MOV CL, 5
  207.   SHL DI, CL
  208.   PUSH SI
  209.   PUSH DS
  210.   CLI
  211.   MOV SI, OFFSET FontOpenReg
  212.   CALL SetRegisters
  213.   POP DS
  214.   POP SI
  215.   MOV AX, DI
  216. @@1 :
  217.   MOV DI, AX
  218.   MOV CX, BX
  219.   REP MOVSB
  220.   ADD AX, 0020h
  221.   DEC CharCount
  222. JNE @@1
  223.   MOV SI, OFFSET FontCloseReg
  224. CALL SetRegisters
  225.   STI
  226.   POP ES
  227.   POP DS
  228. END; { SetTextFont }
  229.  
  230. FUNCTION GetTextFont; assembler;
  231. Asm
  232.   MOV AX, 1130h
  233.   MOV BH, FontCode
  234.   INT 10h
  235.   MOV AX, BP
  236.   MOV DX, ES
  237. END; { GetTextFont }
  238.  
  239. PROCEDURE WriteStr (X, Y : BYTE; S : STRING; Color : TTextAttr); EXTERNAL;
  240.  
  241. PROCEDURE WriteStrV (X, Y : BYTE; S : STRING; Color : TTextAttr);
  242. VAR Index : INTEGER;
  243. BEGIN
  244.   FOR Index := 1 TO LENGTH (S) DO
  245.     WriteChar (X, PRED (Y + Index), 1, S [Index], Color)
  246. END; { WriteStrV }
  247.  
  248. PROCEDURE WriteChar (X, Y, Count : BYTE; Ch : CHAR; Color : TTextAttr);
  249. EXTERNAL;
  250.  
  251. PROCEDURE FillWin (Ch : CHAR; Color : TTextAttr); EXTERNAL;
  252. PROCEDURE WriteWin (VAR Buf); EXTERNAL;
  253. PROCEDURE ReadWin (VAR Buf); EXTERNAL;
  254. FUNCTION  WinSize : WORD; EXTERNAL;
  255.  
  256. PROCEDURE SaveWin (VAR W : TWinState);
  257. BEGIN
  258.   W.WindMin := WindMin;
  259.   W.WindMax := WindMax;
  260. W.WHEREX := WHEREX;
  261.   W.WHEREY := WHEREY;
  262. W.TextAttr := TextAttr
  263. END; { SaveWin }
  264.  
  265. PROCEDURE RestoreWin (VAR W : TWinState);
  266. BEGIN
  267.   WindMin := W.WindMin;
  268.   WindMax := W.WindMax;
  269.   GOTOXY (W.WHEREX, W.WHEREY);
  270.   TextAttr := W.TextAttr
  271. END; { RestoreWin }
  272.  
  273. PROCEDURE GetFrame (FrameNum : BYTE; VAR Frame : TFrame);
  274. BEGIN
  275.   CASE FrameNum OF
  276.     frSingle : Frame := SingleFrame;
  277.     frDouble : Frame := DoubleFrame;
  278.     frSingleDouble : Frame := SingleDoubleFrame;
  279. frDoubleSingle : Frame := DoubleSingleFrame;
  280.     frBar : Frame := BarFrame;
  281. ELSE FILLCHAR (Frame, SIZEOF (Frame), BYTE ( - 1) )
  282.   END
  283. END; { GetFrame }
  284.  
  285. PROCEDURE FrameWin (Title : TitleStr;
  286.   Frame : TFrame; TitleColor, FrameColor : TTextAttr);
  287.  
  288. VAR W, H, Y : WORD;
  289.  
  290. BEGIN
  291. W := LO (WindMax) - LO (WindMin) + 1;
  292. H := HI (WindMax) - HI (WindMin) + 1;
  293. WriteChar (1, 1, 1, Frame [1], FrameColor);
  294. WriteChar (2, 1, W - 2, Frame [2], FrameColor);
  295. WriteChar (W, 1, 1, Frame [3], FrameColor);
  296. IF LENGTH (Title) > W - 2 THEN Title [0] := CHR (W - 2);
  297. WriteStr ( (W - LENGTH (Title) ), 1, Title, TitleColor);
  298.  
  299. FOR Y := 2 TO H - 1 DO
  300. BEGIN
  301. WriteChar (1, Y, 1, Frame [4], FrameColor);
  302.     WriteChar (W, Y, 1, Frame [5], FrameColor)
  303. END;
  304.   WriteChar (1, H, 1, Frame [6], FrameColor);
  305.   WriteChar (2, H, W - 2, Frame [7], FrameColor);
  306.   WriteChar (W, H, 1, Frame [8], FrameColor);
  307.   INC (WindMin, $0101);
  308.   DEC (WindMax, $0101)
  309. END; { FrameWin }
  310.  
  311. PROCEDURE UnFrameWin;
  312. BEGIN
  313.   DEC (WindMin, $0101);
  314.   INC (WindMax, $0101)
  315. END; { UnFrameWin }
  316.  
  317. FUNCTION ScrReadChar; assembler;
  318. Asm
  319.   LES DI, Screen
  320.   XOR AH, AH
  321.   MOV AL, Y
  322. DEC AX
  323.   MUL ScreenWidth
  324.   SHL AX, 1
  325.   XOR DH, DH
  326.   MOV DL, X
  327.   SHL DX, 1
  328.   DEC DX
  329.   DEC DX
  330.   ADD AX, DX
  331.   MOV DI, AX
  332.   MOV AL, BYTE PTR [ES : DI]
  333.   {ScrReadChar := Char(Ptr(Seg(Screen^),
  334.     (Y - 1) * ScreenWidth * 2 + (X * 2) - 2)^)}
  335. END; { ScrReadChar }
  336.  
  337. PROCEDURE ScrWriteChar; assembler;
  338. Asm
  339.   LES DI, Screen
  340.   XOR AH, AH
  341. MOV AL, Y
  342.   DEC AX
  343.   MUL ScreenWidth
  344.   SHL AX, 1
  345.   XOR DH, DH
  346.   MOV DL, X
  347.   SHL DX, 1
  348.   DEC DX
  349.   DEC DX
  350.   ADD AX, DX
  351.   MOV DI, AX
  352.   MOV AL, Ch
  353.   MOV BYTE PTR [ES : DI], AL
  354.   {Char(Ptr(Seg(Screen^),
  355.     (Y - 1) * ScreenWidth * 2 + (X * 2) - 2)^) := Ch}
  356. END; { ScrWriteChar }
  357.  
  358. FUNCTION ScrReadAttr; assembler;
  359. Asm
  360. LES DI, Screen
  361.   XOR AH, AH
  362.   MOV AL, Y
  363.   DEC AX
  364.   MUL ScreenWidth
  365.   SHL AX, 1
  366.   XOR DH, DH
  367.   MOV DL, X
  368.   SHL DX, 1
  369.   DEC DX
  370.   ADD AX, DX
  371.   MOV DI, AX
  372.   MOV AL, BYTE PTR [ES : DI]
  373.   {ScrReadAttr := TTextAttr(Ptr(Seg(Screen^),
  374.     (Y - 1) * ScreenWidth * 2 + (X * 2) - 1)^)}
  375. END; { ScrReadAttr }
  376.  
  377. PROCEDURE ScrWriteAttr; assembler;
  378. Asm
  379. LES DI, Screen
  380.   XOR AH, AH
  381.   MOV AL, Y
  382.   DEC AX
  383.   MUL ScreenWidth
  384.   SHL AX, 1
  385.   XOR DH, DH
  386.   MOV DL, X
  387.   SHL DX, 1
  388.   DEC DX
  389.   ADD AX, DX
  390.   MOV DI, AX
  391.   MOV AL, Color
  392.   MOV BYTE PTR [ES : DI], AL
  393.   {TTextAttr(Ptr(Seg(Screen^),
  394. (Y - 1) * ScreenWidth * 2 + (X * 2) - 1)^) := Color}
  395. END; { ScrWriteAttr }
  396.  
  397. PROCEDURE WindowIndirect (Rect : TRect);
  398. BEGIN
  399.   WITH Rect DO WINDOW (Left, Top, Right, Bottom)
  400. END; { WindowIndirect }
  401.  
  402. FUNCTION PtInRect (X, Y : BYTE; Rect : TRect) : BOOLEAN;
  403. BEGIN
  404.   WITH Rect DO
  405.     PtInRect := (X IN [Left..Right]) AND (Y IN [Top..Bottom])
  406. END; { PtInRect }
  407.  
  408. PROCEDURE GetWindowRect (VAR Rect : TRect); assembler;
  409. Asm
  410.   LES DI, Rect
  411.   MOV AX, WindMin
  412.   MOV BX, WindMax
  413. INC AL
  414.   INC AH
  415.   INC BL
  416.   INC BH
  417. MOV [ES : DI] (TRect) .Left, AL
  418.   MOV [ES : DI] (TRect) .Top, AH
  419.   MOV [ES : DI] (TRect) .Right, BL
  420.   MOV [ES : DI] (TRect) .Bottom, BH
  421. END; { GetWindowRect }
  422.  
  423. PROCEDURE GetWindowRectExt (X1, Y1, X2, Y2 : BYTE; VAR Rect : TRect); assembler;
  424. Asm
  425.   LES DI, Rect
  426.   MOV AL, X1
  427.   MOV AH, Y1
  428.   MOV BL, X2
  429.   MOV BH, Y2
  430.   MOV [ES : DI] (TRect) .Left, AL
  431.   MOV [ES : DI] (TRect) .Right, BL
  432. MOV [ES : DI] (TRect) .Top, AH
  433.   MOV [ES : DI] (TRect) .Bottom, BH
  434. END; { GetWindowRectExt }
  435.  
  436. PROCEDURE ClearWin (X1, Y1, X2, Y2 : BYTE; Color : TTextAttr); assembler;
  437. Asm
  438.   MOV AX, 0600h
  439.   MOV BH, Color
  440.   MOV CL, X1
  441.   DEC CL
  442.   MOV CH, Y1
  443.   DEC CH
  444.   MOV DL, X2
  445.   DEC DL
  446.   MOV DH, Y2
  447.   DEC DH
  448.   INT 10h
  449. END; { ClearWin }
  450.  
  451. PROCEDURE ShadowWin;
  452. VAR P, I : BYTE;
  453. BEGIN
  454.   I := Y2 + 1;
  455. FOR P := X1 + 2 TO X2 + 2 DO
  456.     ScrWriteAttr (P, I, ScrReadAttr (P, I) AND WinShadowAttr);
  457.   I := X2 + 1;
  458.   FOR P := Y1 + 1 TO Y2 + 1 DO
  459.   BEGIN
  460.     ScrWriteAttr (I, P, ScrReadAttr (I, P) AND WinShadowAttr);
  461.     ScrWriteAttr (I + 1, P, ScrReadAttr (I + 1, P) AND WinShadowAttr)
  462.   END
  463. END; { ShadowWin }
  464.  
  465. PROCEDURE CreateWin (X1, Y1, X2, Y2 : BYTE;
  466.   TitleColor, FrameColor : TTextAttr; Title : TitleStr);
  467. VAR
  468. W, H : WORD;
  469. DX, DY : BYTE;
  470. F : TFrame;
  471. BEGIN
  472. IF WinFrame <> frNone THEN
  473. BEGIN
  474. GetFrame (WinFrame, F);
  475. IF WinExplodeDelay <> 0 THEN
  476. BEGIN
  477. DX := X1 + 2;
  478. DY := Y1 + 2;
  479. REPEAT
  480. IF WinShadow = TRUE THEN
  481. ShadowWin (X1, Y1, DX, DY);
  482. WINDOW (X1, Y1, DX, DY);
  483. FrameWin (Title, F, TitleColor, FrameColor);
  484. ClearWin (X1 + 1, Y1 + 1, DX - 1, DY - 1, FrameColor);
  485.  IF DX < X2 THEN INC (DX, 2);
  486.  IF DX > X2 THEN DX := X2;
  487. IF DY < Y2 THEN INC (DY);
  488. DELAY (WinExplodeDelay)
  489. UNTIL (DX = X2) AND (DY = Y2)
  490. END;
  491. IF WinShadow = TRUE THEN ShadowWin (X1, Y1, X2, Y2);
  492. WINDOW (X1, Y1, X2, Y2);
  493. FrameWin (Title, F, TitleColor, FrameColor);
  494. ClearWin (SUCC (X1), SUCC (Y1), PRED (X2), PRED (Y2), FrameColor)
  495.   END;
  496.   WINDOW (X1, Y1, X2, Y2);
  497.   IF WinShadow THEN INC (WindMax, $0102)
  498. END; { CreateWin }
  499.  
  500. PROCEDURE CreateWinIndirect;
  501. BEGIN
  502.   WITH WS, WS.Rect DO
  503.     CreateWin (Left, Top, Right, Bottom, TitleColor, FrameColor, Title)
  504. END; { CreateWinIndirect }
  505.  
  506. FUNCTION OpenWin (X1, Y1, X2, Y2 : BYTE;
  507.   TitleColor, FrameColor : TTextAttr; Title : TitleStr) : BOOLEAN;
  508. VAR W : PWinRec;
  509. BEGIN
  510.   OpenWin := FALSE;
  511.   IF MAXAVAIL > SIZEOF (TWinRec) THEN
  512. BEGIN
  513.     NEW (W);
  514.     W^.Next := TopWindow;
  515.     SaveWin (W^.State);
  516.     IF MAXAVAIL > LENGTH (Title) + 1 THEN
  517.     BEGIN
  518.       GETMEM (W^.Title, LENGTH (Title) + 1);
  519.       W^.Title^ := Title;
  520.       W^.TitleColor := TitleColor;
  521.       W^.FrameColor := FrameColor;
  522.       WINDOW (X1, Y1, X2, Y2);
  523.       IF WinShadow = TRUE THEN INC (WindMax, $0102);
  524.       IF MAXAVAIL > WinSize THEN
  525.       BEGIN
  526. W^.Size := WinSize;
  527. GETMEM (W^.Buffer, W^.Size);
  528. ReadWin (W^.Buffer^);
  529. CreateWin (X1, Y1, X2, Y2, TitleColor, FrameColor, Title);
  530.  TopWindow := W;
  531. INC (WinCount);
  532. OpenWin := TRUE
  533.       END
  534.     END
  535.   END
  536. END; { OpenWin }
  537.  
  538. FUNCTION OpenWinIndirect;
  539. BEGIN
  540.   WITH WS, WS.Rect DO OpenWinIndirect := OpenWin (Left,
  541.     Top, Right, Bottom, TitleColor, FrameColor, Title)
  542. END; { OpenWinIndirect }
  543.  
  544. FUNCTION CloseWin : BOOLEAN;
  545. VAR W : PWinRec;
  546. BEGIN
  547.   CloseWin := FALSE;
  548.   IF Assigned (TopWindow) AND (WinCount > 0) THEN
  549.   BEGIN
  550. W := TopWindow;
  551.     WITH W^ DO
  552.     BEGIN
  553.       WriteWin (Buffer^);
  554.       FREEMEM (Buffer, W^.Size);
  555.       FREEMEM (Title, LENGTH (Title^) + 1);
  556.       RestoreWin (State);
  557.       TopWindow := Next
  558.     END;
  559.     DISPOSE (W);
  560.     DEC (WinCount);
  561.     CloseWin := TRUE
  562.   END
  563. END; { CloseWin }
  564.  
  565. FUNCTION MoveWin;
  566. VAR W : PWinRec;
  567. BEGIN
  568.   MoveWin := FALSE;
  569. IF (MAXAVAIL > SIZEOF (TWinRec) ) AND Assigned (TopWindow) THEN
  570.   BEGIN
  571.     NEW (W);
  572.     IF MAXAVAIL > WinSize THEN
  573.     BEGIN
  574.       SaveWin (W^.State);
  575.       W^.State.WindMin := MakeWord (Top, Left) - $0101;
  576.       W^.State.WindMax := W^.State.WindMin + WindMax - WindMin;
  577.  
  578.       IF WinShadow THEN DEC (WindMax, $0102);
  579.       W^.Size := WinSize;
  580.  
  581.       GETMEM (W^.Buffer, W^.Size);
  582.       ReadWin (W^.Buffer^);
  583.  
  584. IF WinShadow THEN INC (WindMax, $0102);
  585.       WriteWin (TopWindow^.Buffer^);
  586.  
  587.       RestoreWin (W^.State);
  588. ReadWin (TopWindow^.Buffer^);
  589.  
  590.       IF WinShadow THEN DEC (WindMax, $0102);
  591.       WriteWin (W^.Buffer^);
  592.       IF WinShadow THEN
  593.       BEGIN
  594. ShadowWin (Left, Top, SUCC (LO (WindMax) ), SUCC (HI (WindMax) ) );
  595. INC (WindMax, $0102)
  596.       END;
  597.       FREEMEM (W^.Buffer, W^.Size);
  598.       MoveWin := TRUE
  599.     END;
  600.     DISPOSE (W)
  601.   END
  602. END; { MoveWin }
  603.  
  604. FUNCTION SaveDOSScreen;
  605. BEGIN
  606.   IF NOT GetDisplay IN [gdEGA..gdMCGA] THEN UseFade := FALSE;
  607.  
  608.   OldCursor := GetCursorType;
  609.   SetCursor (CursorOff);
  610.  
  611.   IF UseFade THEN FadeOut (FadeDelay);
  612.  
  613.   asm
  614.     PUSH WORD PTR [WinShadow]
  615.     MOV WinShadow, FALSE
  616.   END;
  617.  
  618.   SaveDOSScreen := OpenWin (1, 1,
  619.     ScreenWidth, ScreenHeight, Black, Black, None);
  620.  
  621.   asm
  622. POP WORD PTR [WinShadow]
  623.   END;
  624.  
  625.   IF RestoreScreen THEN WriteWin (TopWindow^.Buffer^);
  626.  
  627.   IF UseFade THEN FadeIn (0)
  628.  
  629. END; { SaveDOSScreen }
  630.  
  631. FUNCTION RestoreDOSScreen;
  632. BEGIN
  633.   IF NOT GetDisplay IN [gdEGA..gdMCGA] THEN UseFade := FALSE;
  634.  
  635.   WINDOW (1, 1, ScreenWidth, ScreenHeight);
  636.   asm
  637.     MOV WinShadow, FALSE
  638.   END;
  639.   IF UseFade THEN SetBrightness (0);
  640.   RestoreDOSScreen := CloseWin;
  641.  
  642.   IF UseFade THEN FadeIn (FadeDelay);
  643.  
  644.   SetCursorType (OldCursor);
  645. SetCursor (CursorOn)
  646. END; { RestoreDOSScreen }
  647.  
  648. PROCEDURE SetBlink (BlinkOn : BOOLEAN);
  649. CONST PortVal : ARRAY [0..4] OF BYTE = ($0C, $08, $0D, $09, $09);
  650. VAR
  651.   PortNum : WORD;
  652.   Index, PVal : BYTE;
  653. BEGIN
  654.   IF LastMode = Mono THEN
  655.   BEGIN
  656.     PortNum := $3B8;
  657.     Index := 4
  658.   END ELSE
  659.     IF GetDisplay IN [gdEGA..gdMCGA] THEN
  660. BEGIN
  661.       INLINE (
  662. $8A / $5E / < BlinkOn /     { MOV BL, [BP+<BlinkOn] }
  663. $B8 / $03 / $10 /          { MOV AX, $1003 }
  664. $CD / $10);             { MOV $10 }
  665.       EXIT
  666.     END ELSE
  667.       BEGIN
  668. PortNum := $3D8;
  669. CASE LastMode OF
  670.   0..3 : Index := LastMode;
  671.   ELSE EXIT
  672. END
  673.       END;
  674.    PVal := PortVal [Index];
  675.    IF BlinkOn THEN
  676.    PVal := PVal OR $20;
  677.    Port [PortNum] := PVal
  678. END; { SetBlink }
  679.  
  680. FUNCTION HeapFunc (Size : WORD) : INTEGER; far; assembler;
  681. Asm
  682.   MOV AX, 1
  683. END; { HeapFunc }
  684.  
  685. BEGIN
  686.   HeapError := @HeapFunc;
  687.   WinCount := 0;
  688.   WinShadow := TRUE;
  689.   WinFrame := frSingle;
  690.   WinExplodeDelay := 10; { set no explode }
  691.   TopWindow := NIL;
  692.   IF LastMode = Mono THEN
  693.     Screen := PTR (SegB000, 0) ELSE
  694.   BEGIN
  695.     Screen := PTR (SegB800, 0);
  696.     IF (LastMode AND Font8x8) <> 0 THEN
  697. ScreenHeight := Mem [Seg0040 : $0084] ELSE ScreenHeight := 25
  698. END;
  699. ScreenWidth := MemW [Seg0040 : $004A];
  700. InitCol;       { Save original palette }
  701. SetBlink (TRUE) { Set blinking }
  702. END. { Win.Pas }
  703.  
  704. {--------------------------------  XX3402 CODE ---------------------}
  705. { CUT OUT THE FOLLOWING AND USE XX3402 TO DECODE TO OBTAIN WIN.OBJ  }
  706.  
  707. * XX3402 - 000678 - 090894 - - 72 - - 85 - 53801 - - - - - - - - - WIN.OBJ - - 1 - OF - - 1
  708. U + Y + - rRdPWt - IooHW0 + + + + + QJ5JmMawUELBnNKpWP4Jm60 - KNL7nOKxi61AiAda61k - + uTBN
  709. 0Fo5RqZi9Y3HHKe6 + k - + uImK + U + + O6U1 + 20VZ7M4 + + F2EJF - FdU5 + 2U + + + 6 - + FKK - U + 2Eox2
  710. FIKM - k + cEE21 + E5mX - s + 0IB6FIB9IotDJk + 5JoZCF2p7HU + 5JoZCF2p - K + - gY + w + + + 66Jp77
  711. J2JLGIsh + + 0lY + s + + + 65FYZAH3R7HWA + + 04E2 + + + + UZLIYZIFIB6EJ6H + + 0NY + w + + + 66Jp77
  712. J2JHJ36 + + + 1HY + s + + + 65JoZCIoZOFH6 - + DqE1U + + + URGFI32JoZC8 + + + 7sU2 + 20W + N4UFE20
  713. + + - JWyn2LUUaWUyyJE1ckE - RmUc + JMjgWYs8jbg + u92 + LQc8 + 9tv + Cg6jdc + ukCyeU - JWykn
  714. mMgK + + 081U + + 8gd - IJ7Ku9o + LZdNzgMuBU2 + RixRmUE + 5cda - gJq02Nm3em9qCmc + LLvyimc
  715. + LHvWwCfyy9g5wCgey9w5wC8FUW8NUNm36jMv8U - RTjuv8U - RDi9kujvsiz1wuj15UMTWzT2
  716. TUPc2E07TUMTklv3RUPc - E07RUMTkr6JfMjMv8U - RTjuv8U - RDi9kujvsin1wuL1WZMCzgc0
  717. 3U + + QZMu3U + + Rp08RUnynU6q + E - mFHcq + E - rDn9hsniU + + + ekjv + CgVm + cf6i2 + + Xg08lWPq
  718. 7Yc + AjM1kh5UWzWs + 9UaU1t7 + + Rp + fGkXg0uqUDwU1s + + + 5ztgCV + + + f - U + + - E2 - xiHFsAja
  719. b2k + l + dI + gEOJ + 9273E0l0ZI + gEiJ + 92BkM - + gEv - U21l2o4 + ED2pkM - + gHR - U21lCU4 + E92
  720. vUM - + wHr - U21lGk4 + E53AkM - + wIr - U20Gcc0 + + - o
  721. * * * * * END OF BLOCK 1 * * * * *
  722.  
  723.  
  724. {--------------------------------   ASSEMBLY CODE ---------------------}
  725. { COMPILE THE FOLLOWING WITH TASM                                      }
  726.  
  727. ; {*** WIN.ASM ***}
  728.  
  729.         TITLE   WIN
  730.  
  731.         LOCALS  @@
  732.  P286
  733.  
  734. ; Coordinate RECORD
  735.  
  736. X               EQU     (BYTE PTR 0)
  737. Y               EQU     (BYTE PTR 1)
  738.  
  739. ; BIOS workspace equates
  740.  
  741. CrtMode         EQU     (BYTE PTR 49H)
  742. CrtWidth        EQU     (BYTE PTR 4AH)
  743.  
  744. DATA    SEGMENT WORD PUBLIC
  745.  
  746. ; Externals from CRT UNIT
  747.  
  748.         EXTRN   CheckSnow : BYTE, WindMin : WORD, WindMax : WORD
  749.  
  750. DATA    ENDS
  751.  
  752. CODE    SEGMENT BYTE PUBLIC
  753.  
  754.         ASSUME  CS : CODE, DS : DATA
  755.  
  756. ; PROCEDURE WriteStr (X, Y : BYTE; S : STRING; Attr : BYTE);
  757.  
  758.         PUBLIC  WriteStr
  759.  
  760. WriteStr :
  761.  
  762.         PUSH    BP
  763. MOV     BP, SP
  764.         LES     BX, [BP + 8]
  765.         MOV     CL, ES : [BX]
  766.         MOV     SI, OFFSET CS : CrtWriteStr
  767.         CALL    CrtWrite
  768.         POP     BP
  769.         RETF    10
  770.  
  771. ; PROCEDURE WriteChar (X, Y, Count : BYTE; Ch : CHAR; Attr : BYTE);
  772.  
  773.         PUBLIC  WriteChar
  774.  
  775. WriteChar :
  776.  
  777.         PUSH    BP
  778.         MOV     BP, SP
  779.         MOV     CL, [BP + 10]
  780.         MOV     SI, OFFSET CS : CrtWriteChar
  781. CALL    CrtWrite
  782.         POP     BP
  783.         RETF    10
  784.  
  785. ; PROCEDURE FillWin (Ch : CHAR; Attr : BYTE);
  786.  
  787.         PUBLIC  FillWin
  788.  
  789. FillWin :
  790.  
  791.         MOV     SI, OFFSET CS : CrtWriteChar
  792.         JMP     SHORT CommonWin
  793.  
  794. ; PROCEDURE ReadWin (VAR Buf);
  795.  
  796.         PUBLIC  ReadWin
  797.  
  798. ReadWin :
  799.  
  800.         MOV     SI, OFFSET CS : CrtReadWin
  801.         JMP     SHORT CommonWin
  802.  
  803. ; PROCEDURE WriteWin (VAR Buf);
  804.  
  805.         PUBLIC  WriteWin
  806.  
  807. WriteWin :
  808.  
  809.         MOV     SI, OFFSET CS : CrtWriteWin
  810.  
  811. ; Common FillWin / ReadWin / WriteWin routine
  812.  
  813. CommonWin :
  814.  
  815.         PUSH    BP
  816.         MOV     BP, SP
  817. XOR     CX, CX
  818.         MOV     DX, WindMin
  819.         MOV     CL, WindMax.X
  820.         SUB     CL, DL
  821.         INC     CX
  822. @@1 :    PUSH    CX
  823.         PUSH    DX
  824.         PUSH    SI
  825.         CALL    CrtBlock
  826.         POP     SI
  827.         POP     DX
  828.         POP     CX
  829.         INC     DH
  830.         CMP     DH, WindMax.Y
  831.         JBE     @@1
  832.         POP     BP
  833.         RETF    4
  834.  
  835. ; WRITE STRING TO screen
  836.  
  837. CrtWriteStr :
  838.  
  839.         PUSH    DS
  840.         MOV     AH, [BP + 6]
  841.         LDS     SI, [BP + 8]
  842.         INC     SI
  843.         JC      @@4
  844. @@1 :    LODSB
  845.         MOV     BX, AX
  846. @@2 :    IN      AL, DX
  847.         TEST    AL, 1
  848.         JNE     @@2
  849.         CLI
  850. @@3 :    IN      AL, DX
  851.         TEST    AL, 1
  852.         JE      @@3
  853. MOV     AX, BX
  854.         STOSW
  855.         STI
  856.         LOOP    @@1
  857.         POP     DS
  858.         RET
  859. @@4 :    LODSB
  860.         STOSW
  861.         LOOP    @@4
  862.         POP     DS
  863.         RET
  864.  
  865. ; WRITE characters TO screen
  866.  
  867. CrtWriteChar :
  868.  
  869.         MOV     AL, [BP + 8]
  870.         MOV     AH, [BP + 6]
  871. JC      @@4
  872.         MOV     BX, AX
  873. @@1 :    IN      AL, DX
  874.         TEST    AL, 1
  875.         JNE     @@1
  876.         CLI
  877. @@2 :    IN      AL, DX
  878.         TEST    AL, 1
  879.         JE      @@2
  880.         MOV     AX, BX
  881.         STOSW
  882.         STI
  883.         LOOP    @@1
  884.         RET
  885. @@4 :    REP     STOSW
  886.         RET
  887.  
  888. ; READ WINDOW buffer from screen
  889.  
  890. CrtReadWin :
  891.  
  892.         PUSH    DS
  893.         PUSH    ES
  894.         POP     DS
  895.         MOV     SI, DI
  896.         LES     DI, [BP + 6]
  897.         CALL    CrtCopyWin
  898.         MOV     [BP + 6], DI
  899.         POP     DS
  900.         RET
  901.  
  902. ; WRITE WINDOW buffer TO screen
  903.  
  904. CrtWriteWin :
  905.  
  906.         PUSH    DS
  907. LDS     SI, [BP + 6]
  908.         CALL    CrtCopyWin
  909.         MOV     [BP + 6], SI
  910.         POP     DS
  911.         RET
  912.  
  913. ; WINDOW buffer COPY routine
  914.  
  915. CrtCopyWin :
  916.  
  917.         JC      @@4
  918. @@1 :    LODSW
  919.         MOV     BX, AX
  920. @@2 :    IN      AL, DX
  921.         TEST    AL, 1
  922.         JNE     @@2
  923.         CLI
  924. @@3 :    IN      AL, DX
  925. TEST    AL, 1
  926.         JE      @@3
  927.         MOV     AX, BX
  928.         STOSW
  929.         STI
  930.         LOOP    @@1
  931.         RET
  932. @@4 :    REP     MOVSW
  933.         RET
  934.  
  935. ; DO screen operation
  936. ; IN    CL = Buffer LENGTH
  937. ;       SI = WRITE PROCEDURE POINTER
  938. ;       BP = Stack frame POINTER
  939.  
  940. CrtWrite :
  941.  
  942.         MOV     DL, [BP + 14]
  943. DEC     DL
  944.         ADD     DL, WindMin.X
  945.         JC      CrtExit
  946.         CMP     DL, WindMax.X
  947.         JA      CrtExit
  948.         MOV     DH, [BP + 12]
  949.         DEC     DH
  950.         ADD     DH, WindMin.Y
  951.         JC      CrtExit
  952.         CMP     DH, WindMax.Y
  953.         JA      CrtExit
  954.         XOR     CH, CH
  955.         JCXZ    CrtExit
  956.         MOV     AL, WindMax.X
  957.         SUB     AL, DL
  958.         INC     AL
  959.         CMP     CL, AL
  960.         JB      CrtBlock
  961. MOV     CL, AL
  962.  
  963. ; DO screen operation
  964. ; IN    CL = Buffer LENGTH
  965. ;       DX = CRT coordinates
  966. ;       SI = PROCEDURE POINTER
  967.  
  968. CrtBlock :
  969.  
  970.         MOV     AX, 40H
  971.         MOV     ES, AX
  972.         MOV     AL, DH
  973.         MUL     ES : CrtWidth
  974.         XOR     DH, DH
  975.         ADD     AX, DX
  976.         SHL     AX, 1
  977.         MOV     DI, AX
  978.         MOV     AX, 0B800H
  979. CMP     ES : CrtMode, 7
  980.         JNE     @@1
  981.         MOV     AH, 0B0H
  982. @@1 :    MOV     ES, AX
  983.         MOV     DX, 03DAH
  984.         CLD
  985.         CMP     CheckSnow, 1
  986.         JMP     SI
  987.  
  988. ; EXIT from screen operation
  989.  
  990. CrtExit :
  991.  
  992.         RET
  993.  
  994. ; FUNCTION WinSize : WORD;
  995.  
  996.         PUBLIC  WinSize
  997.  
  998. WinSize :
  999.  
  1000. MOV     AX, WindMax
  1001. SUB     AX, WindMin
  1002. ADD     AX, 101H
  1003. MUL     AH
  1004. SHL     AX, 1
  1005. RETF
  1006.  
  1007. CODE    ENDS
  1008.  
  1009. END
  1010.  
  1011.  
  1012.